#ifndef __IAP_HANDLE_H
#define __IAP_HANDLE_H
#include <stdbool.h>
#include "includes.h"



/*
片内Flash划分说明
IAP代码区12KB: 0x08000000-0x08002FFF (page0-5)
	第0页	0x0800 0000 - 0x0800 07FF	2KB
	第1页	0x0800 0800 - 0x0800 0FFF	2KB
	第2页	0x0800 1000 - 0x0800 17FF	2KB
	......
	第5页	0x0800 2800 - 0x0800 2FFF	2KB

用户代码区56KB: 0x08003000-0x08010FFF (pase6-33)
	第6页	0x0800 3000 - 0x0800 37FF	2KB
	第7页	0x0800 3800 - 0x0800 3FFF	2KB
	......
	第32页	0x0801 0000 - 0x0801 07FF	2KB
	第33页	0x0801 0800 - 0x0801 0FFF	2KB

升级代码区56KB: 0x08011000-0x0801EFFF (page34-61)
	第34页	0x0801 1000 - 0x0801 17FF	2KB
	第35页	0x0801 1800 - 0x0801 1FFF	2KB
	......
	第60页	0x0801 E000- 0x0801 E7FF	2KB
	第61页	0x0801 E800 - 0x0801 EFFF	2KB

用户数据区4KB: 0x0801F000-0x0801FFFF (page62-63)
	第62页	0x0801 F000 - 0x0801 F7FF	2KB
	第63页	0x0801 F800 - 0x0801 FFFF	2KB
*/

#define IAP_UPDATE_FLAG		0xAA55A55A
#define IAP_UPDATE_CLEAR	0xFFFFFFFF

#define IF_FLASH_PAGE_SIZE		(2048u)

#define APP_FLASH_SIZE		(FLASH_PAGE_SIZE*APP_PAGE_NUMBER) //56KB
#define USER_APP_ADDR		(0x08003000)
#define USER_UPDATE_ADDR	(0x08011000)
#define USER_DATA_ADDR		(0x0801F000)
#define ADDR_MAX_SIZE		(0x0801FFFF)
#define HDWARE_VERSION_ADDR	(USER_DATA_ADDR+sizeof(BIN_FILE_INFO_T) + (4-(USER_DATA_ADDR+sizeof(BIN_FILE_INFO_T))%4)) //硬件版本号
#define BOOT_VERSION_ADDR   (FLASH_BASE+IF_FLASH_PAGE_SIZE-4)




/* Exported macro ------------------------------------------------------------*/
#define FRAM_MAX (1200u)
#define DATA_MAX (1022u) 
#define FRAM_MIN (8u)
#define SEND_DATA_BUF_SIZE (16u)


#define UART_DATA_HEAD 0xFF55  
#define UART_DATA_HEAD_H 0xFF       
#define UART_DATA_HEAD_L 0x55

#define MIN(a, b) (a<b?a:b)

#define IN
#define OUT
#define INOUT


typedef enum
{
	DEV_SUCCESS			= 0,	//状态：0x00-操作成功，
	DEV_BUSY			= 1,	//0x01设备忙，
	NOT_ENOUGH_MEMORY	= 2,	//0x02-内存不足，
	CRC_ERROR			= 3,	//0x03-CRC错误，
	PACK_LOSS			= 4,	//0x04-帧序号不连续
	CMD_NOTSUPORT		= 5,	//0x05-命令不支持
	DATA_LEN_ERROR		= 6,	//0x06-数据长度错误
	DEV_ERROR			= 255	//设备出错
}STATUS_E;

typedef enum
{
	CMD_CTRL_E		= 0xA0, //控制指令：用于工程调试，单条指令下发（待制定）
	CMD_MENUENTER_E	= 0x01, //功能指令：菜谱录入（操作屏下发，主控板响应）
	CMD_MENULOAD_E	= 0x02, //菜谱下发（操作屏下发，主控板响应）
	CMD_UPDATE_E	= 0x03, //软件升级（操作屏下发，主控板响应，待制定）
	CMD_STATUS_E	= 0x04, //机器状态（操作屏下发，主控板上报状态）
	CMD_VERSION_E	= 0x05, //版本信息（操作屏下发，主控板上报软硬件版本信息，待制定）
	CMD_REQ_E		= 0x06, //请求信息（主控板发起，操作屏做对应动作）
	CMD_STOP_E		= 0x07, //停止（操作屏下发，主控板响应，在不同指令类别下，设备响应不同见备注）
	CMD_CANCEL_E	= 0x08, //取消（操作屏下发，主控板响应）
	CMD_ACK_E		= 0xB0 //应答指令：主控板、操作屏应答使用）
}CMD_E;

typedef struct
{
	uint8_t ucFramHeadH; //帧头0
	uint8_t ucFramHeadL; //帧头1
	uint8_t usFramLenH; //帧长0
	uint8_t usFramLenL; //帧长1
	uint8_t ucCmd; //命令
	uint8_t ucFramSerialNo; //帧序号
	uint8_t ucaBuf[DATA_MAX+2]; //数据+CRC
}UART_FRAM_T;


typedef struct
{
	uint8_t ucBoadNo;		//目标板号（1Byte）
	uint8_t ucVersionX;		//软件版本(3Byte):软件版本：X
	uint8_t ucVersionY;		//软件版本(3Byte):软件版本：Y
	uint8_t ucVersionZ;		//软件版本(3Byte):软件版本：Z

	uint8_t ucFramTotal;	//数据总帧数(1Byte)
	uint8_t ucResBuf1[3];

	uint32_t uiFileSize;	//文件大小(3Byte)

	uint16_t usFileCrc;		//数据+CRC
	uint8_t ucResBuf2[2];

	uint32_t uiLoadover;	//下载完成
}BIN_FILE_INFO_T;

void UartHandle_Ack_Cmd(IN uint8_t ucCmd, IN uint8_t ucStatus);
void UartHandle_Cmd_Execute(IN UART_FRAM_T *pstFramCfg);
void Iap_Jump_App(IN uint32_t uiAppAddr);
void Iap_Data_Read(OUT uint8_t *pucBuf, IN uint32_t uiAddr, IN uint32_t uiLen);
STATUS_E Iap_Data_Write(IN uint8_t *pucBuf, IN uint32_t uiAddr, IN uint32_t uiLen);
STATUS_E Iap_If_Erase(IN uint32_t uiAddr, IN uint32_t uiFileLen);
STATUS_E Iap_Data_ReadAndCmp(IN uint8_t *pucBuf, IN uint32_t uiAddr, IN uint32_t uiLen);
STATUS_E Iap_Data_Crc16Check(IN uint32_t uiAddr, IN uint32_t uiLen, IN uint16_t usCrcModbus);
STATUS_E Iap_Set_LoadOverFlag(IN int32_t uiLoadover);
STATUS_E Iap_Update_BinFile(void);

void Init_Board_Info(uint8_t board_id,uint8_t hardwareVersion);

void UartHandle_RecAndOperate(void);

extern volatile uint32_t vg_uiIapWaitTimeMs;
extern volatile uint8_t vg_ucWaitTimeOutFlag;
extern volatile uint8_t vg_ucIapLoadOverFlag;
#endif

